import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'
import { useAuthStore } from '@/stores/auth'
// 简单的 toast 替代方案
const showToast = (message: string, type: 'success' | 'error' | 'warning' | 'info' = 'info') => {
  // 使用浏览器原生 alert 作为临时替代
  if (type === 'error' || type === 'warning') {
    alert(message)
  } else {
    console.log(`[${type.toUpperCase()}] ${message}`)
  }
}
import type { ApiResponse } from '@/types'

// 创建axios实例
const request: AxiosInstance = axios.create({
  // 优先使用环境变量中的API基础URL
  baseURL: (import.meta as any).env?.VITE_API_BASE_URL || '/api',
  timeout: parseInt((import.meta as any).env?.VITE_API_TIMEOUT) || 30000,
  headers: {
    'Content-Type': 'application/json',
  },
  withCredentials: false,
})

// 请求拦截器
request.interceptors.request.use(
  (config) => {
    // 添加认证token
    const authStore = useAuthStore()
    if (authStore.token) {
      config.headers = config.headers || {}
      config.headers.Authorization = `Bearer ${authStore.token}`
    }

    // 添加请求ID用于追踪
    config.headers = config.headers || {}
    config.headers['X-Request-ID'] = generateRequestId()

    return config
  },
  (error: AxiosError) => {
    console.error('Request interceptor error:', error)
    return Promise.reject(error)
  }
)

// 响应拦截器
request.interceptors.response.use(
  (response: AxiosResponse<ApiResponse>) => {
    const { data } = response

    // 兼容不同后端业务码：允许 code 为 200 或 0，或无 code 字段
    const hasCode = data && typeof (data as any).code !== 'undefined'
    const code = hasCode ? (data as any).code : undefined
    const okCodes = [200, 0]

    if (hasCode && !okCodes.includes(code)) {
      // 根据错误码处理不同情况
      switch (code) {
        case 401: {
          const authStore = useAuthStore()
          authStore.logout()
          showToast((data as any).message || '登录已过期，请重新登录', 'error')
          window.location.href = '/login'
          break
        }
        case 403:
          showToast((data as any).message || '权限不足', 'error')
          break
        case 404:
          showToast((data as any).message || '资源不存在', 'error')
          break
        case 429:
          showToast((data as any).message || '请求过于频繁，请稍后再试', 'warning')
          break
        default:
          showToast((data as any).message || '请求失败', 'error')
      }

      return Promise.reject(new Error((data as any).message || '请求失败'))
    }

    return response
  },
  (error: AxiosError<ApiResponse>) => {
    if (error.response) {
      // 服务器响应了错误状态码
      const { status, data } = error.response
      switch (status) {
        case 400:
          showToast(data?.message || '请求参数错误', 'error')
          break
        case 401: {
          const authStore = useAuthStore()
          authStore.logout()
          showToast('登录已过期，请重新登录', 'error')
          window.location.href = '/login'
          break
        }
        case 403:
          showToast('权限不足', 'error')
          break
        case 404:
          showToast('资源不存在', 'error')
          break
        case 422:
          showToast(data?.message || '数据验证失败', 'error')
          break
        case 429:
          showToast('请求过于频繁，请稍后再试', 'warning')
          break
        case 500:
          showToast('服务器内部错误', 'error')
          break
        case 502:
          showToast('网关错误', 'error')
          break
        case 503:
          showToast('服务暂时不可用', 'error')
          break
        default:
          showToast(data?.message || `请求失败 (${status})`, 'error')
      }
    } else if (error.request) {
      // 请求已发出但没有收到响应
      if (error.code === 'ECONNABORTED') {
        showToast('请求超时，请稍后重试', 'error')
      } else {
        showToast('网络连接失败，请检查网络设置', 'error')
      }
    } else {
      // 请求配置出错
      showToast('请求配置错误', 'error')
    }

    console.error('Response interceptor error:', error)
    return Promise.reject(error)
  }
)

// 生成请求ID
function generateRequestId(): string {
  return `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
}

// 封装常用请求方法
export const http = {
  get<T = any>(url: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
    return request.get<ApiResponse<T>>(url, config).then(res => res.data)
  },

  post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
    return request.post<ApiResponse<T>>(url, data, config).then(res => res.data)
  },

  put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
    return request.put<ApiResponse<T>>(url, data, config).then(res => res.data)
  },

  delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
    return request.delete<ApiResponse<T>>(url, config).then(res => res.data)
  },

  patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
    return request.patch<ApiResponse<T>>(url, data, config).then(res => res.data)
  },

  // 上传文件
  upload<T = any>(url: string, file: File | FormData, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
    const formData = file instanceof FormData ? file : new FormData()
    if (file instanceof File) {
      formData.append('file', file)
    }

    return request.post<ApiResponse<T>>(url, formData, {
      ...config,
      headers: {
        ...config?.headers,
        'Content-Type': 'multipart/form-data',
      },
    }).then(res => res.data)
  },

  // 下载文件
  download(url: string, filename?: string, config?: AxiosRequestConfig): Promise<void> {
    return request.get(url, {
      ...config,
      responseType: 'blob',
    }).then(response => {
      const blob = new Blob([response.data])
      const downloadUrl = window.URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = downloadUrl
      link.download = filename || 'download'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      window.URL.revokeObjectURL(downloadUrl)
    })
  }
}

export { request }
export default request

